/**
 * 代码没啥问题，就是研究区域太大，在GEE上跑会超出内存限制，因此随机森林参数都挺小的
 * OA能达到0.9，KA能达到0.81
 * 可进一步缩小研究区域，调整随机森林参数
 *  · 可以增加背景样本（如 1000）以提高分类效果
 *  · 如果数据量较大，可以增加树的数量（如 100），提高分类器稳定性
 * 遇事不决再问问ChatGPT和DeepSeek
 */


// 导入数据
var ROI = Fujin;
var Maize = FujinMaize;
var Rice = FujinRice;
var Soybean = FujinSoybean;

// 设置土地覆盖类别
Maize = Maize.map(function(feature) { return feature.set('landcover', 2); }); // 玉米
Rice = Rice.map(function(feature) { return feature.set('landcover', 1); });  // 水稻
Soybean = Soybean.map(function(feature) { return feature.set('landcover', 3); });  // 大豆

// 显示研究区
Map.centerObject(ROI, 6);
Map.addLayer(ROI, {color: 'red', fillColor: '00000000'}, "FujinEdge");

// Sentinel-2 去云处理
function maskS2clouds(image) {
  var qa = image.select('QA60');
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
              .and(qa.bitwiseAnd(cirrusBitMask).eq(0));
  return image.updateMask(mask).divide(10000);
}

// 构建 Sentinel-2 影像集合
var dataset = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate('2022-05-01', '2022-08-31')
                  .filterBounds(ROI)
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
                  .map(maskS2clouds);

// 计算指数
var add_RS_index = function(img) {
  var ndvi = img.normalizedDifference(['B8', 'B4']).rename('NDVI');
  var ndwi = img.normalizedDifference(['B3', 'B8']).rename('NDWI');
  var mndwi = img.normalizedDifference(['B3', 'B11']).rename('MNDWI');
  var lswi = img.normalizedDifference(['B8','B11']).rename('LSWI');
  var ndsvi = img.normalizedDifference(['B11','B4']).rename('NDSVI');
  var ndti = img.normalizedDifference(['B11','B12']).rename('NDTI');
  var evi = img.expression(
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR': img.select('B8'),
      'RED': img.select('B4'),
      'BLUE': img.select('B2')
  }).rename('EVI');
  var ndpi = img.expression(
  '(NIR - (0.74 * RED + 0.26 * SWIR)) / (NIR + (0.74 * RED + 0.26 * SWIR))',
  {
    'NIR': img.select('B8'), 
    'RED': img.select('B4'),
    'SWIR': img.select('B11')
  }).rename('NDPI');

  //绿色叶绿素植被指数
  var gcvi = img.expression(
  '((NIR / GREEN) - 1)',
  {
    'NIR': img.select('B8'),
    'GREEN': img.select('B3')
  }).rename('GCVI');
  
  return img.addBands([ndvi, ndwi, mndwi, lswi, ndti, ndsvi, evi, ndpi, gcvi]);
};

dataset = dataset.map(add_RS_index);

// 计算年度中位影像
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B11','B12', 
            'NDVI', 'NDWI','MNDWI','LSWI','NDTI','NDSVI', 'EVI','NDPI','GCVI'];
var imgcol_median = dataset.select(bands).median();
var construct_img = imgcol_median.clip(ROI);

// === 方法 1.1: 自动提取背景样本点 ===
// NDVI 低于 0.2 且 NDWI 低于 0.1 认为是背景
var backgroundMask = construct_img.select('NDVI').lt(0.3).and(construct_img.select('EVI').lt(0.3));
var backgroundSamples = backgroundMask.selfMask().sample({
  region: ROI,
  scale: 20,
  numPixels: 500,  // 选取 500 个背景样本
  geometries: true
}).map(function(f) { return f.set('landcover', 0); });  // 设置 landcover = 0（背景）

// 合并样本点
var train_points = Maize.merge(Rice).merge(Soybean).merge(backgroundSamples);

// 样本点抽样
var train_data = construct_img.sampleRegions({
  collection: train_points,
  properties: ['landcover'],
  scale: 30,
  tileScale: 16
});

// 样本集划分
var withRandom = train_data.randomColumn('random');
var split = 0.7; 
var trainingPartition = withRandom.filter(ee.Filter.lt('random', split));
var testingPartition = withRandom.filter(ee.Filter.gte('random', split));

// 训练随机森林分类器
var rf = ee.Classifier.smileRandomForest({
  numberOfTrees: 10,
  bagFraction: 0.7
}).train({
  features: trainingPartition,
  classProperty: 'landcover',
  inputProperties: construct_img.bandNames()
});

// 进行分类
var img_classification = construct_img.classify(rf);

// === 方法 3: 后处理去除背景 ===
// 使用 NDVI 进一步去除背景
var final_classification = img_classification.updateMask(
  construct_img.select('NDVI').gte(0.3).or(construct_img.select('EVI').gte(0.3))
);

// 计算混淆矩阵
var test = testingPartition.classify(rf);
var confusionMatrix = test.errorMatrix('landcover', 'classification');
print('Confusion Matrix', confusionMatrix);
print('Overall Accuracy', confusionMatrix.accuracy());
print('Kappa Accuracy', confusionMatrix.kappa());

// 显示分类结果
Map.addLayer(final_classification, {min: 0, max: 3, palette: ['gray', 'yellow', 'green', 'orange']}, "Final Classification");

// 获取随机森林模型的特征重要性
var featureImportance = rf.explain().get('importance');
print('原始特征重要性:', featureImportance);

// 将重要性转换为列表并排序（降序）
var importanceDict = ee.Dictionary(featureImportance);
var bandNames = construct_img.bandNames(); // 获取所有波段和指数名称
var importanceList = importanceDict.values(bandNames); // 按bandNames顺序提取重要性值

// 创建包含波段名称和重要性的FeatureCollection
var importanceFC = ee.FeatureCollection(
  bandNames.map(function(band) {
    return ee.Feature(null, {
      'Band': band,
      'Importance': importanceDict.get(band)
    });
  })
);

// 按重要性降序排序
var sortedImportance = importanceFC.sort('Importance', false);
print('排序后的特征重要性:', sortedImportance);

// 提取重要性值最大的前10个特征
var top10 = sortedImportance.limit(10);
print('Top 10重要特征:', top10);